<template>
    <div id="pieEcharts" style="width: 100%;height: 100%;"></div>
</template>
<script setup>
import { onMounted, ref, getCurrentInstance, watch } from 'vue';
import { formatTipVlaue } from '@/utils';
import * as echarts from 'echarts';
import "echarts-gl";
import tipImage from '../../assets/images/tooltip.png'
const { proxy } = getCurrentInstance();

const props = defineProps({
    seriesData: {
        type: Array,
        required: true
    },
    unit: {
        type: String,
        default: '人'
    },
    fixed: {
        type: Number,
        default: 0
    },
    currentStep: {
        default: "0"
    }
});

let myChart = null;
let optionData = props.seriesData;
//监听数据变化，可以做更新图标操作
watch(() => props.seriesData, (val, oldVal) => {
    // console.log("PieEcharts3D Change>>>");
    optionData = val;
    if (myChart) {
        myChart.setOption(getPie3D(optionData, 0));
    }
});



onMounted(() => {
    myChart = echarts.init(document.getElementById('pieEcharts'));
    myChart.setOption(getPie3D(optionData, 0), false);
    //重置大小无效，原因待查
    proxy.$bus.on('resize', (res) => {
        myChart.resize();
    })
});


/*************************
生成扇形的曲面参数方程 生成 3D 扇形环曲面：
   【 getParametricEquation 函数说明 】 
      startRatio（浮点数）: 当前扇形起始比例，取值区间 [0, endRatio)
      endRatio（浮点数）: 当前扇形结束比例，取值区间 (startRatio, 1]
      isSelected（布尔值）:是否选中，效果参照二维饼图选中效果（单选）
      isHovered（布尔值）: 是否放大，效果接近二维饼图高亮（放大）效果（未能实现阴影）
      k（0~1之间的浮点数）：用于参数方程的一个参数，取值 0~1 之间，通过「内径/外径」的值换算而来。
      h :饼图的初始高度
 *************************/
function getParametricEquation(startRatio, endRatio, isSelected, isHovered, k, h) {
    const midRatio = (startRatio + endRatio) / 2;
    const startRadian = startRatio * Math.PI * 2;
    const endRadian = endRatio * Math.PI * 2;
    const midRadian = midRatio * Math.PI * 2;
    // 如果只有一个扇形，则不实现选中效果。
    if (startRatio === 0 && endRatio === 1) {
        isSelected = false;
    }
    k = typeof k !== 'undefined' ? k : 1 / 3;
    const offsetX = isSelected ? Math.cos(midRadian) * 0.1 : 0;
    const offsetY = isSelected ? Math.sin(midRadian) * 0.1 : 0;
    // 鼠标滑过时外环放大大小
    const hoverRate = isHovered ? 1.05 : 1;
    // 返回曲面参数方程
    return {
        u: {
            min: -Math.PI,
            max: Math.PI * 3,
            step: Math.PI / 32,
        },

        v: {
            min: 0,
            max: Math.PI * 2,
            step: Math.PI / 20,
        },

        x(u, v) {
            if (u < startRadian) {
                return offsetX + Math.cos(startRadian) * (1 + Math.cos(v) * k) * hoverRate;
            }
            if (u > endRadian) {
                return offsetX + Math.cos(endRadian) * (1 + Math.cos(v) * k) * hoverRate;
            }
            return offsetX + Math.cos(u) * (1 + Math.cos(v) * k) * hoverRate;
        },

        y(u, v) {
            if (u < startRadian) {
                return offsetY + Math.sin(startRadian) * (1 + Math.cos(v) * k) * hoverRate;
            }
            if (u > endRadian) {
                return offsetY + Math.sin(endRadian) * (1 + Math.cos(v) * k) * hoverRate;
            }
            return offsetY + Math.sin(u) * (1 + Math.cos(v) * k) * hoverRate;
        },

        z(u, v) {
            if (u < -Math.PI * 0.5) {
                return Math.sin(u);
            }
            if (u > Math.PI * 2.5) {
                return Math.sin(u) * h * 0.1;
            }
            // 当前图形的高度是Z根据h（每个value的值决定的）
            return Math.sin(v) > 0 ? 1 * h * 0.1 : -1;
        },
    };
}

/********** 
生成模拟 3D 饼图的配置项
   【 getPie3D 函数说明 】 :
      pieData（object）：饼图数据
      internalDiameterRatio（0~1之间的浮点数）：内径/外径的值（默认值 1/2），当该值等于 0 时，为普通饼图
   // 为每一个饼图数据，生成一个 series-surface 配置
   // 使用遍历计算出的数据和 sumValue，调用 getParametricEquation 函数，实现每一个扇形。
*/
function getPie3D(pieData, internalDiameterRatio) {
    const series = [];
    let sumValue = 0;
    let startValue = 0;
    let endValue = 0;
    const legendData = [];
    const k =
        typeof internalDiameterRatio !== 'undefined'
            ? (1 - internalDiameterRatio) / (1 + internalDiameterRatio)
            : 1 / 3;
    //自定义图例name的样式
    var optionRich = {
        a: {
            width: 80,
            fontSize: 12,
            fontWeight: 400,
            color: '#FFFFFF',//#99C3E5
            lineHeight: 20,
            padding: [0, 0, 0, 0],
        },
    };
    //自定义图例value值的样式
    pieData.forEach((ele, i) => {
        optionRich[i] = {
            width: 20,
            fontSize: 12,
            fontWeight: 400,
            lineHeight: 20,
            color: '#FFFFFF',
            align: 'center',
            padding: [0, 0, 0, 0],
        };
    });
    for (let i = 0; i < pieData.length; i += 1) {
        sumValue += pieData[i].value;
        const seriesItem = {
            name: typeof pieData[i].name === 'undefined' ? `series${i}` : pieData[i].name,
            type: 'surface',
            parametric: true,
            wireframe: {
                show: false,
            },
            pieData: pieData[i],
            pieStatus: {
                selected: false,
                hovered: false,
                k,
            },
            itemStyle: {
                color: pieData[i]['color'], // 自定义颜色
            },
        };
        if (typeof pieData[i].itemStyle !== 'undefined') {
            const { itemStyle } = pieData[i];
            // eslint-disable-next-line no-unused-expressions
            typeof pieData[i].itemStyle.color !== 'undefined' ? (itemStyle.color = pieData[i].itemStyle.color) : null;
            // eslint-disable-next-line no-unused-expressions
            typeof pieData[i].itemStyle.opacity !== 'undefined'
                ? (itemStyle.opacity = pieData[i].itemStyle.opacity)
                : null;

            seriesItem.itemStyle = itemStyle;
        }
        series.push(seriesItem);
    }
    for (let i = 0; i < series.length; i += 1) {
        endValue = startValue + series[i].pieData.value;
        series[i].pieData.startRatio = startValue / sumValue;
        series[i].pieData.endRatio = endValue / sumValue;
        series[i].parametricEquation = getParametricEquation(
            series[i].pieData.startRatio,
            series[i].pieData.endRatio,
            false,
            false,
            k,
            10//在此处传入饼图初始高度h
        );
        startValue = endValue;
        legendData.push(series[i].name);
    }
    // 准备待返回的配置项，把准备好的series 传入。
    const option = {
        // backgroundColor: "#123756",
        legend: {
            type: 'scroll',
            show: true,
            orient: "vertical",
            selectedMode: false,
            top: 'middle',
            right: '5%',
            icon: 'rect', //图例的图标形状
            itemHeight: 6, //图例的图标高度
            itemWidth: 12, //图例的图标宽度
            itemGap: 10, //图例之间的间隔
            pageIconSize: 10,
            pageIconColor: "#29bca8",
            pageIcons: {
                vertical: [
                    "path://M472.064 272.448l-399.232 399.232c-22.08 22.08-22.08 57.792 0 79.872 22.016 22.016 57.792 22.08 79.872 0L512 392.256l359.296 359.296c22.016 22.016 57.792 22.08 79.872 0 22.08-22.08 22.016-57.792 0-79.872L551.936 272.448C529.856 250.432 494.144 250.432 472.064 272.448z",
                    "path://M472.064 751.552 72.832 352.32c-22.08-22.08-22.08-57.792 0-79.872 22.016-22.016 57.792-22.08 79.872 0L512 631.744l359.296-359.296c22.016-22.016 57.792-22.08 79.872 0 22.08 22.08 22.016 57.792 0 79.872l-399.232 399.232C529.856 773.568 494.144 773.568 472.064 751.552z"
                ]
            },
            formatter: (name) => {
                if (optionData.length) {
                    let index = 0;
                    let value = 0;
                    for (let i = 0; i < optionData.length; i++) {
                        if (optionData[i].name == name) {
                            value = optionData[i].value ? optionData[i].value : 0;
                            index = i;
                        }
                    }
                    return `{a|${name}}{${index}|${value}}`;
                }
            },
            textStyle: {
                rich: optionRich
            },
            pageTextStyle: {
                color: '#fff'
            }
        },
        tooltip: {
            show: true,
            trigger: 'item',
            padding: [0, 0, 0, 0],
            axisPointer: {
                lineStyle: {
                    width: 1,
                    type: 'solid',
                    color: '#00D1FF'
                }
            },
            backgroundColor: 'transparent',
            borderColor: 'transparent',
            shadowColor: 'transparent',
            formatter: (params) => {
                if (params.seriesName !== 'mouseoutSeries') {
                    let value = formatTipVlaue(optionData[params.seriesIndex].value, props.fixed);
                    return `<div style="width:150px;height:55px; background:url(${tipImage}) no-repeat;background-size:contain;padding:5px 10px;">
                              <p style="font-size:12px;color:rgba(214, 243, 255, 0.9);display:flex;align-items: center ;margin-top:0px">
                                <span>${params.seriesName} :&nbsp;</span>
                                <span>${value} ${props.unit}</span>   
                              </p>
                              <p style="font-size:12px;color:rgba(214, 243, 255, 0.9);display:flex;align-items: center; margin-top:5px">
                                <span>时间 :&nbsp;</span>
                                <span>第${props.currentStep}秒</span> 
                              </p>
                         </div>`
                }
                return '';

            },
        },
        xAxis3D: {
            min: -1,
            max: 1,
        },
        yAxis3D: {
            min: -1,
            max: 1,
        },
        zAxis3D: {
            min: -1,
            max: 1,
        },
        grid3D: {
            show: false,
            boxHeight: 25,//修改立体饼图的高度
            top: '0',
            left: '-20%',
            viewControl: {
                // 3d效果可以放大、旋转等，
                alpha: 35,//饼图翻转的程度
                beta: 30,
                rotateSensitivity: 1,
                zoomSensitivity: 0,
                panSensitivity: 0,
                autoRotate: false,//是否自动旋转
                distance: 350,//距离越小看到的饼图越大
            },
        },
        series,
    };
    return option;
}
</script>
<style scoped></style>